package com.jyw.business.obstacles.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.jyw.business.obstacles.domain.ObsOrderFault;
import com.jyw.business.obstacles.domain.ObsOrderSend;
import com.jyw.business.obstacles.service.IObsOrderSendService;
import com.jyw.common.constant.CacheConstants;
import com.jyw.common.core.domain.entity.SysUser;
import com.jyw.common.core.redis.RedisCache;
import com.jyw.common.utils.DateUtils;
import com.jyw.system.domain.SysTeam;
import com.jyw.system.domain.SysUserTeam;
import com.jyw.system.domain.vo.SysOrderReminderConfigVo;
import com.jyw.system.enums.MessageTypeEnum;
import com.jyw.system.service.ISysMessageService;
import com.jyw.system.service.ISysOrderReminderConfigService;
import com.jyw.system.service.ISysUserTeamService;
import com.jyw.system.utils.TeamUtils;
import com.jyw.system.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 超时未接单定时任务
 */
@Component("waitAcceptTask")
@Slf4j
public class WaitAcceptTask {

    @Resource
    private IObsOrderSendService sendService;

    @Resource
    private ISysOrderReminderConfigService reminderConfigService;

    @Resource
    private RedisCache redisCache;

    @Resource
    private ISysUserTeamService userTeamService;

    @Resource
    private ISysMessageService messageService;

    /**
     * 超时未接单定时任务提醒
     * 工单超时未接单通知
     * 工单标题
     * 故障分类
     * 报修科室
     * 待接单人
     * 工单编号
     */
    public void remind() {
        SysOrderReminderConfigVo config = reminderConfigService.getDefaultConfig();
        //开启了超时未接单提醒
        if (config.getReceiveTimeoutRemind() && config.getReceiveTimeoutMinute() != null
                && config.getReceiveTimeoutInterval() != null && StrUtil.isNotEmpty(config.getReceiveTimeoutReminder())) {
            log.info("运行工单超时未接单提醒");
            //读取超时几分钟
            Integer minute = config.getReceiveTimeoutMinute();
            //计算时间,小于该时间的都属于超时
            Date timeOutDate = DateUtils.addMinutes(DateUtils.getNowDate(), -minute);
            //查询出超时未接单的工单
            List<ObsOrderFault> obsOrderFaults = sendService.listTimeOut(timeOutDate);
            List<SysTeam> sysTeams = TeamUtils.cacheList();
            List<SysUser> sysUsers = UserUtils.cacheList();
            if (CollUtil.isNotEmpty(obsOrderFaults)) {
                Integer interval = config.getReceiveTimeoutInterval();
                String reminder = config.getReceiveTimeoutReminder();
                TimeUnit timeUnit = TimeUnit.SECONDS;
                Integer reminderSecond = interval * 60;
                obsOrderFaults.forEach(data -> {
                    String orderNum = data.getOrderNum();
                    String cacheKey = CacheConstants.WAIT_ACCEPT_REMIND_KEY + orderNum;
                    String oldCache = redisCache.getCacheObject(cacheKey);
                    // 不存在缓存 发送消息
                    if (StrUtil.isEmpty(oldCache)) {
                        //查询需要派单人员/小组,查询处理人或者组长
                        List<ObsOrderSend> sendList = sendService.lambdaQuery().eq(ObsOrderSend::getOrderNum, orderNum).list();
                        if (CollUtil.isNotEmpty(sendList)) {
                            Integer messageType = MessageTypeEnum.SYS_ORDER.getValue();
                            String msg = "工单号【" + orderNum + "】已超时未接单，请知晓";
                            List<Long> sendAllUser = new ArrayList<>();
                            List<Long> sendTeamLeaders = new ArrayList<>();
                            List<Long> sendAllTeam = new ArrayList<>();
                            //先查询派单给个人的人员
                            List<Long> sendUser = sendList.stream().filter(send -> send.getSendType().equals(1) && !ObjectUtils.isEmpty(send.getSendUser())).map(ObsOrderSend::getSendUser).distinct().collect(Collectors.toList());
                            List<Long> sendUserTeam = sendList.stream().filter(send -> send.getSendType().equals(2) && !ObjectUtils.isEmpty(send.getSendTeam())).map(ObsOrderSend::getSendTeam).distinct().collect(Collectors.toList());
                            //查询出派单给小组的数据
                            List<Long> sendTeam = sendList.stream().filter(send -> !ObjectUtils.isEmpty(send.getSendTeam())).map(ObsOrderSend::getSendTeam).distinct().collect(Collectors.toList());
                            if (CollUtil.isNotEmpty(sendUser)) {
                                // 添加处理人
                                sendAllUser.addAll(sendUser);
                                //查询人员的小组
                                List<SysUserTeam> userTeam = userTeamService.lambdaQuery().in(SysUserTeam::getUserId, sendUser).list();
                                //查询通知的组长 需要通知的组长
                                if (CollUtil.isNotEmpty(userTeam)) {
                                    List<Long> userTeamIds = userTeam.stream().map(SysUserTeam::getTeamId).collect(Collectors.toList());
                                    if (CollUtil.isNotEmpty(userTeamIds)) {
                                        List<Long> teamLeader = userTeamService.lambdaQuery().in(SysUserTeam::getTeamId, userTeamIds).eq(SysUserTeam::getIsLeader, 1).list().stream().map(SysUserTeam::getUserId).distinct().collect(Collectors.toList());
                                        if (CollUtil.isNotEmpty(teamLeader)) {
                                            sendTeamLeaders.addAll(teamLeader);
                                        }
                                    }
                                }
                            }
                            // 有组员的小组
                            if (CollUtil.isNotEmpty(sendUserTeam)) {
                                sendAllTeam.addAll(sendUserTeam);
                            }
                            // 未分组的小组
                            if (CollUtil.isNotEmpty(sendTeam)) {
                                sendAllTeam.addAll(sendTeam);
                            }
                            // 存在派单小组
                            if (CollUtil.isNotEmpty(sendAllTeam)) {
                                // 查询通知组员
                                List<Long> teamUsers = userTeamService.lambdaQuery().in(SysUserTeam::getTeamId, sendAllTeam).eq(SysUserTeam::getIsLeader, 0).list().stream().map(SysUserTeam::getUserId).distinct().collect(Collectors.toList());
                                if (CollUtil.isNotEmpty(teamUsers)) {
                                    sendAllUser.addAll(teamUsers);
                                }
                                // 查询通知组长
                                List<Long> teamLeaders = userTeamService.lambdaQuery().in(SysUserTeam::getTeamId, sendAllTeam).eq(SysUserTeam::getIsLeader, 1).list().stream().map(SysUserTeam::getUserId).distinct().collect(Collectors.toList());
                                if (CollUtil.isNotEmpty(teamLeaders)) {
                                    sendTeamLeaders.addAll(teamLeaders);
                                }
                            }
                            List<Long> allUsers = new ArrayList<>();
                            // 处理人
                            if (reminder.contains("1") && CollUtil.isNotEmpty(sendAllUser)) {
                                allUsers.addAll(sendAllUser);
                            }
                            // 组长
                            if (reminder.contains("2") && CollUtil.isNotEmpty(sendTeamLeaders)) {
                                allUsers.addAll(sendTeamLeaders);
                            }
                            if (CollUtil.isNotEmpty(allUsers)) {
                                List<Long> sendUserIds = allUsers.stream().distinct().collect(Collectors.toList());
                                messageService.sendBatchSysMessage(messageType, sendUserIds, msg);
                                // 添加缓存
                                redisCache.setCacheObject(cacheKey, orderNum, reminderSecond, timeUnit);
                                //封装处理人名称
                                /*String makeUser = sendUserIds.stream().map(uid -> {
                                    SysUser sysUser = sysUsers.stream().filter(user -> user.getUserId().equals(uid)).findFirst().orElse(null);
                                    if (!ObjectUtils.isEmpty(sysUser)) {
                                        return sysUser.getNickName();
                                    }
                                    return null;
                                }).filter(nickName -> !ObjectUtils.isEmpty(nickName)).collect(Collectors.joining(","));*/
                            }
                        }
                    }
                });
            }
        }
    }
}
